package cn.jingyuan.swan.cloud.web;

import cn.jingyuan.swan.cloud.core.RestResult;
import cn.jingyuan.swan.cloud.core.Result;
import cn.jingyuan.swan.cloud.core.ResultUtils;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.lang.reflect.Type;
import java.util.Objects;


// FIXME 待修正
public class DefaultJsonResponseBodyAdvice implements ResponseBodyAdvice<Object> {

    protected static final HttpStatus OK = HttpStatus.OK;

    @Override
    // FIXME json 判定不完全
    public boolean supports(MethodParameter returnType, Class converterType) {
        // ResponseEntity 或 HttpEntity 响应类型不予处理
        Type genericParameterType = returnType.getGenericParameterType();
        String genericParameterTypeTypeName = genericParameterType.getTypeName();

        if (ResponseEntity.class.getName().equals(genericParameterTypeTypeName)) {
            return false;
        }

        if (HttpEntity.class.getName().equals(genericParameterTypeTypeName)) {
            return false;
        }

        // FIXME 判定是否为 json 输出
        // FIXME 判定是否为 RetainOriginal

        /*
            判断 MediaType 是否为 json
                1、RequestMapping 属性 produces 是否为 json 类型
                2、Controller 是否被 RestController.class 修饰
                3、method 是否被 ResponseBody.class 修饰
         */

        if (null != returnType.getMethod().getDeclaringClass().getAnnotation(RestController.class)) {
            return true;
        }

        return null != returnType.getMethod().getAnnotation(RequestBody.class);
    }

    @Override
    public Result<? extends Object> beforeBodyWrite(
        Object body,
        MethodParameter returnType,
        MediaType selectedContentType,
        Class selectedConverterType,
        ServerHttpRequest request,
        ServerHttpResponse response) {
        // FIXME 修正逻辑


        if (body instanceof Void || Objects.isNull(body)) {
            Result<Object> result = ResultUtils.ok();
            response.setStatusCode(OK);

            return result;
        }


        boolean isRestResult = body instanceof RestResult;
        if (isRestResult) {
            RestResult<?> result = (RestResult) body;

            Integer status = result.getHttpStatus();
            if (null == status) {  // status 为 null 默认设置为：200
                status = OK.value();
            }

            result.setHttpStatus(status);
            response.setStatusCode(HttpStatus.valueOf(status));

            return result;

        } else {
            Result<Object> result = ResultUtils.ok(body);
            response.setStatusCode(OK);

            return result;
        }
    }

}
